<template>
  <view class="poster-page">
    <canvas
      class="canvas"
      :style="{ width: `${data.cancasW}px`, height: `${data.canvasH}px` }"
      type="2d"
      id="share-poster"
    ></canvas>
    <uni-popup ref="pop" type="center">
      <view class="poster-contanier">
        <view class="pic-box">
          <image
            class="pic"
            :lazy-load="true"
            :show-menu-by-longpress="true"
            :src="data.poster"
            mode="widthFix"
          />
        </view>

        <view class="share-list">
          <view
            class="share-box"
            v-for="(item, index) in data.picShareList"
            :key="index"
            @click="share(item.type)"
          >
            <button
              class="button"
              v-if="item.type == 1"
              open-type="share"
            ></button>
            <view class="icon-box" :style="{ backgroundColor: item.color }"
              ><text class="nb_icon" :class="item.icon"></text
            ></view>
            <view class="txt">{{ item.txt }}</view>
          </view>
        </view>
      </view>
    </uni-popup>
    <tt-loading :type="2" :ready="data.ready"></tt-loading>
  </view>
</template>
<script setup lang="ts">
/**
 * 模块引入
 */
import {
  reactive,
  getCurrentInstance,
  onMounted,
  defineProps,
  defineExpose,
  ref,
  watchEffect,
} from "vue";
import { onLoad } from "@dcloudio/uni-app";
const instance = getCurrentInstance();
const { proxy } = getCurrentInstance();
/**
 * 接口
 */
import { getCode } from "@/apis/member.ts";
import { picShareList } from "@/data/index.ts";
/**
 * 父组件数据
 */
const props = defineProps({
  posterData: {
    type: Object,
  },
});
watchEffect(() => {
  console.log(props.posterData);
  setTimeout(() => {
    data.poster = "";
    handleHeight();
  }, 10);
});
/**
 * 子组件方法
 */
const pop = ref();
/**
 * 数据
 */
const data = reactive({
  cancasW: 300,
  canvasH: 500,
  textNum: 22, //每行文字个数
  imgWidth: 280, //头部图片宽度
  imgHeight: 0, //头部图片高度
  contentHeight: 0, //文字高度
  show: false,
  poster: "",
  picShareList,
  ready: true,
  currentHeight: 0, //当前页面高度
});
/**
 * 方法
 */
onMounted(() => {
  // handleHeight()
});
const handleHeight = async () => {
  let headImgHeight: any = await new Promise((resolve) => {
    uni.getImageInfo({
      src: props.posterData.image,
      success: (res: any) => {
        data.imgHeight = ((res.height * data.imgWidth) / res.width) * 1.1;
        resolve(data.imgHeight);
      },
      fail: (err: any) => {
        console.log(err);
      },
    });
  });
  let len = Math.ceil(props.posterData.text.length / data.textNum);
  data.contentHeight = len * 18;
  let footerHeight = 60;
  let spaceHeight = 150;
  data.canvasH =
    headImgHeight + data.contentHeight + footerHeight + spaceHeight;
  setTimeout(() => {
    init();
  }, 0);
};
const init = () => {
  const query = uni.createSelectorQuery().in(instance);
  query
    .select("#share-poster")
    .fields({ node: true, size: true })
    .exec(async (res) => {
      const canvas = res[0].node;
      const ctx = canvas.getContext("2d");
      // 清晰度处理
      const dpr = uni.getSystemInfoSync().pixelRatio;
      canvas.width = res[0].width * dpr;
      canvas.height = res[0].height * dpr;

      ctx.scale(dpr, dpr);
      // 绘制海报大小

      circleRect(ctx, 0, 0, data.cancasW, data.canvasH, 5);
      ctx.fillStyle = "white";
      ctx.fillRect(0, 0, data.cancasW, data.canvasH);
      let imgInfo = await getImgInfo(canvas, props.posterData.image, true);
      drawText(ctx, canvas);
      let code = await fetchCode();
      let codeInfo = await getImgInfo(canvas, code);
      ctx.drawImage(
        codeInfo,
        10,
        data.imgHeight + 110 + data.contentHeight,
        50,
        50
      );
      drawtext4(ctx);
      drawImage(ctx, canvas, imgInfo);
      save(canvas);
    });
};

const fetchCode = () => {
  let params = {
    page: props.posterData.path || "pages/read/index/index",
    scene: props.posterData.scene,
    isJob: 1,
  };
  return new Promise((resolve) => {
    getCode(params).then((res: any) => {
      resolve(res.data);
    });
  });
};
const getImgInfo = async (canvas: any, img: any, setHeight: any = false) => {
  return new Promise((resolve: any) => {
    const image = canvas.createImage();
    image.src = img;
    image.onload = () => {
      if (setHeight) {
        data.imgHeight = ((image.height * data.imgWidth) / image.width) * 1.1;
      }
      resolve(image);
    };
  });
};

const drawImage = async (ctx: any, canvas: any, image: any) => {
  // 绘制圆角矩形
  circleRect(ctx, 10, 10, data.imgWidth, data.imgHeight, 5);
  ctx.drawImage(image, 10, 10, data.imgWidth, data.imgHeight);
};
const circleRect = (ctx: any, x: any, y: any, w: any, h: any, r: any) => {
  ctx.beginPath();
  ctx.moveTo(x + r, y);
  ctx.arcTo(x + w, y, x + w, y + h, r);
  ctx.arcTo(x + w, y + h, x, y + h, r);
  ctx.arcTo(x, y + h, x, y, r);
  ctx.arcTo(x, y, x + w, y, r);
  ctx.closePath();
  ctx.strokeStyle = "#FFFFFF"; // 设置绘制圆形边框的颜色
  ctx.stroke();
  ctx.clip();
};
const drawText = (ctx: any, canvas: any) => {
  ctx.font = "normal  14px sans-serif";
  ctx.fillStyle = "#555";
  ctx.fillText(props.posterData.title, 10, data.imgHeight + 40);

  ctx.font = "normal  10px sans-serif";
  ctx.fillStyle = "#555";
  ctx.fillText(`分享自「轻启内招」小程序`, 10, data.imgHeight + 65);

  ctx.font = "normal  12px sans-serif ";
  ctx.fillStyle = "#555";
  let len = Math.ceil(props.posterData.text.length / data.textNum);
  let texts = props.posterData.text;
  for (let i = 0; i < len; i++) {
    let text = texts.substring(0, data.textNum);
    ctx.fillText(text, 10, data.imgHeight + 90 + i * 22);
    texts = texts.slice(data.textNum);
  }
};
const drawtext4 = (ctx: any) => {
  ctx.font = "normal bold 11px sans-serif";
  ctx.fillStyle = "#555";
  ctx.fillText(
    props.posterData.slogen || "轻启内招，帮你找到最适合的工作",
    65,
    data.imgHeight + 125 + data.contentHeight
  );
  ctx.font = "normal  10px sans-serif";
  ctx.fillStyle = "#555";
  ctx.fillText(
    `${props.posterData.from}`,
    65,
    data.imgHeight + 150 + data.contentHeight
  );
};

const save = (canvas: any) => {
  wx.canvasToTempFilePath({
    x: 0,
    y: 0,
    width: data.cancasW * 3,
    height: data.canvasH * 3,
    destWidth: data.cancasW * 5,
    destHeight: data.canvasH * 5,
    canvas: canvas,
    success(res: any) {
      // saveToAlbum(res.tempFilePath)
      console.log(res.tempFilePath);
      data.poster = res.tempFilePath;
      data.ready = true;
    },
    fail(err: any) {
      uni.showToast({
        title: "生成失败",
        icon: "none",
      });
      pop.value.close();
      console.log(err);
    },
  });
};
const saveToAlbum = (img: any) => {
  uni.saveImageToPhotosAlbum({
    filePath: img,
    success: () => {
      console.log("save success");
    },
  });
};
const share = (type: any) => {
  switch (type) {
    case 3:
      wx.showShareImageMenu({
        path: data.poster,
        success: () => {
          pop.value.close();
        },
      });
      break;
    case 4:
      saveToAlbum(data.poster);
      break;
  }
};
const open = () => {
  pop.value.open();
  if (!data.poster) {
    data.ready = false;
  }
};
defineExpose({
  open,
});
</script>
<style lang="scss" scoped>
@import url("@/static/css/theme.scss");
.poster-page {
  .canvas {
    position: fixed;
    top: -100%;
    width: 560rpx;
    height: 900rpx;
  }
  .poster-contanier {
    width: 520rpx;
    .pic-box {
      width: 100%;
      height: 900rpx;
      border-radius: 20rpx;
      background-color: #fff;
      overflow: scroll;
      .pic {
        width: 100%;
      }
    }

    .share-list {
      margin-top: 20rpx;
      display: flex;
      justify-content: space-around;
      .share-box {
        position: relative;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        .button {
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          opacity: 0;
        }
        .icon-box {
          margin-top: 10rpx;
          width: 80rpx;
          height: 80rpx;
          display: flex;
          justify-content: center;
          align-items: center;
          border-radius: 50%;
          .nb_icon {
            color: #fff;
          }
        }

        .txt {
          margin-top: 10rpx;
          font-size: 20rpx;
          color: #fff;
        }
      }
    }
  }
}
</style>
